package org.pentaho.di.trans.steps.esinput;


import org.pentaho.di.core.CheckResultInterface;
import org.pentaho.di.core.Const;
import org.pentaho.di.core.Counter;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.exception.KettleStepException;
import org.pentaho.di.core.exception.KettleXMLException;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMeta;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.core.variables.VariableSpace;
import org.pentaho.di.core.xml.XMLHandler;
import org.pentaho.di.repository.ObjectId;
import org.pentaho.di.repository.Repository;
import org.pentaho.di.shared.SharedObjectInterface;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDataInterface;
import org.pentaho.di.trans.step.StepInterface;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.step.StepMetaInterface;
import org.w3c.dom.Node;

import java.util.List;
import java.util.Map;

public class ESInputMeta extends BaseStepMeta implements StepMetaInterface {
	private static Class<?> PKG = ESInputMeta.class;


	private String esHost;
	private String esPort;
	private String esIndex;
	private String esType;

	public String getESIndexPath() {
		return ESIndexPath;
	}

	public void setESIndexPath(String ESIndexPath) {
		this.ESIndexPath = ESIndexPath;
	}

	private String ESIndexPath;



	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	private String savePath;
	private boolean autoID;
	private boolean autoMemory;
	private boolean useBatchUpdate;

	/** Fields in the table to insert */
	private String[] fieldDatabase;

	private String[] fieldDatabaseType;

	public String[] getFieldDatabaseType() {
		return fieldDatabaseType;
	}

	public void setFieldDatabaseType(String[] fieldDatabaseType) {
		this.fieldDatabaseType = fieldDatabaseType;
	}

	public boolean isAutoMemory() {
		return autoMemory;
	}

	public void setAutoMemory(boolean autoMemory) {
		this.autoMemory = autoMemory;
	}

	public ESInputMeta() {
		super(); // allocate BaseStepMeta
		fieldDatabase = new String[0];
		fieldDatabaseType = new String[0];
	}

	public void allocate(int nrRows) {
		fieldDatabase = new String[nrRows];
		fieldDatabaseType = new String[nrRows];
	}

	// 加载XML
	public void loadXML(Node stepnode, List<DatabaseMeta> databases, Map<String, Counter> counters)
			throws KettleXMLException {
		readData(stepnode, databases);
	}

	public Object clone() {
		ESInputMeta retval = (ESInputMeta) super.clone();

		int nrDatabase = fieldDatabase.length;

		retval.fieldDatabase = new String[nrDatabase];
		retval.fieldDatabaseType = new String[nrDatabase];

		for (int i = 0; i < nrDatabase; i++) {
			retval.fieldDatabase[i] = fieldDatabase[i];
		}

		for (int i = 0; i < nrDatabase; i++) {
			retval.fieldDatabaseType[i] = fieldDatabaseType[i];
		}

		return retval;
	}

	private void readData(Node stepnode, List<? extends SharedObjectInterface> databases) throws KettleXMLException {
		try {
			String con = XMLHandler.getTagValue(stepnode, "connection");
			esHost = XMLHandler.getTagValue(stepnode, "host");
			esPort = XMLHandler.getTagValue(stepnode, "port");
			esIndex = XMLHandler.getTagValue(stepnode, "es_index");
			esType = XMLHandler.getTagValue(stepnode, "es_type");
			ESIndexPath = XMLHandler.getTagValue(stepnode, "ESIndexPath");
			savePath = XMLHandler.getTagValue(stepnode, "savePath");

			autoID = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "auto_id"));

			useBatchUpdate = "Y".equalsIgnoreCase(XMLHandler.getTagValue(stepnode, "use_batch"));

			Node fields = XMLHandler.getSubNode(stepnode, "fields"); //$NON-NLS-1$
			int nrRows = XMLHandler.countNodes(fields, "field"); //$NON-NLS-1$

			allocate(nrRows);

			for (int i = 0; i < nrRows; i++) {
				Node knode = XMLHandler.getSubNodeByNr(fields, "field", i); //$NON-NLS-1$

				fieldDatabase[i] = XMLHandler.getTagValue(knode, "column_name"); //$NON-NLS-1$
				fieldDatabaseType[i] = XMLHandler.getTagValue(knode, "columnType_name"); //$NON-NLS-1$
			}
		} catch (Exception e) {
			throw new KettleXMLException("Unable to load step info from XML", e);
		}
	}

	// 设置默认值
	@Override
	public void setDefault() {
		esHost = "localhost";
		esPort = "9200";
		esIndex = "";
		esType = "";
		ESIndexPath = "";
		savePath = "";
		autoID = false;
	}

	// 添加变量，从XML读取配置值
	@Override
	public String getXML() {
		StringBuilder retval = new StringBuilder();

		retval.append("    " + XMLHandler.addTagValue("host", esHost)); // es数据库地址
		retval.append("    " + XMLHandler.addTagValue("port", esPort)); // es数据库端口
		retval.append("    " + XMLHandler.addTagValue("es_index", esIndex)); //
		retval.append("    " + XMLHandler.addTagValue("es_type", esType)); //
		retval.append("    " + XMLHandler.addTagValue("auto_id", autoID));

		retval.append("    " + XMLHandler.addTagValue("ESIndexPath", ESIndexPath)); //
		retval.append("    " + XMLHandler.addTagValue("savePath", savePath));


		retval.append("    " + XMLHandler.addTagValue("use_batch", useBatchUpdate));

		retval.append("    <fields>").append(Const.CR); //$NON-NLS-1$

		for (int i = 0; i < fieldDatabase.length; i++) {
			retval.append("        <field>").append(Const.CR); //$NON-NLS-1$

			retval.append("          ").append(XMLHandler.addTagValue("column_name", fieldDatabase[i])); //$NON-NLS-1$ //$NON-NLS-2$
			retval.append("          ").append(XMLHandler.addTagValue("columnType_name", fieldDatabaseType[i])); //$NON-NLS-1$ //$NON-NLS-2$
			retval.append("        </field>").append(Const.CR); //$NON-NLS-1$
		}
		retval.append("    </fields>").append(Const.CR); //$NON-NLS-1$

		return retval.toString();
	}

	public void readRep(Repository rep, ObjectId id_step, List<DatabaseMeta> databases, Map<String, Counter> counters)
			throws KettleException {

	}

	public void saveRep(Repository rep, ObjectId id_transformation, ObjectId id_step) throws KettleException {

	}

	public void getFields(RowMetaInterface row, String origin, RowMetaInterface[] info, StepMeta nextStep,
			VariableSpace space) throws KettleStepException {

		ValueMetaInterface outFields = null;

		for (int i = 0; i < fieldDatabase.length; i++) {
			outFields = new ValueMeta(fieldDatabase[i], ValueMeta.getType(fieldDatabaseType[i]));
			row.addValueMeta(outFields);
		}

		ValueMetaInterface typeFields = new ValueMeta("ESType", ValueMeta.getType("String"));
		row.addValueMeta(typeFields);


	}

	public void check(List<CheckResultInterface> remarks, TransMeta transMeta, StepMeta stepMeta, RowMetaInterface prev,
			String input[], String output[], RowMetaInterface info) {

	}

	public StepInterface getStep(StepMeta stepMeta, StepDataInterface stepDataInterface, int cnr, TransMeta transMeta,
			Trans trans) {
		return new ESInput(stepMeta, stepDataInterface, cnr, transMeta, trans);
	}

	public StepDataInterface getStepData() {
		return new ESInputData();
	}

	/**
	 * @return Fields containing the fieldnames in the database insert.
	 */
	public String[] getFieldDatabase() {
		return fieldDatabase;
	}

	/**
	 * @param fieldDatabase
	 *            The fields containing the names of the fields to insert.
	 */
	public void setFieldDatabase(String[] fieldDatabase) {
		this.fieldDatabase = fieldDatabase;
	}

	/**
	 * 
	 * @return esHost
	 */
	public String getEsHost() {
		return esHost;
	}

	/**
	 * 
	 * @param esHost
	 *            to set esHost
	 */
	public void setEsHost(String esHost) {
		this.esHost = esHost;
	}

	/**
	 * 
	 * @return esPort
	 */
	public int getEsPort() {
		return Integer.valueOf(esPort);
	}

	/**
	 * 
	 * @param esPort
	 *            to set esPort
	 */
	public void setEsPort(String esPort) {
		this.esPort = esPort;
	}

	public String getEsIndex() {
		return esIndex;
	}

	public void setEsIndex(String esIndex) {
		this.esIndex = esIndex;
	}

	public String getEsType() {
		return esType;
	}

	public void setEsType(String esType) {
		this.esType = esType;
	}

	public boolean isAutoID() {
		return autoID;
	}

	public void setAutoID(boolean autoID) {
		this.autoID = autoID;
	}

}